package com.dmbjz.coredemo.listener;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

import java.time.Duration;


/**
 * Listener 需要从 META-INF/spring.factories 文件中获取
 * */
@Slf4j
public class MyAppListener implements SpringApplicationRunListener {


    /** SpringApplication.run() 执行 getRunListeners() 方法时触发 */
    @Override
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        log.info("[starting]-正在启动");
    }


    /**
     * 在准备好环境之后，但在创建ApplicationContext之前调用
     */
    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
        log.info("[environmentPrepared]-环境准备完成");
    }


    /**
     * ioc容器创建并准备好，但是 source（主配置类）没加载时调用
     * SpringApplication.run() 执行 prepareContext() 方法时触发
     */
    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        log.info("[contextPrepared]-IOC容器准备完成");
    }


    /**
     * ioc容器加载。但是 IOC 容器还没刷新时调用
     */
    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        log.info("[contextLoaded]-IOC容器加载完成");
    }


    /**
     * IOC容器已刷新（bean创建完成），但尚未调用 CommandLineRunners、ApplicationRunners
     * SpringApplication.run() 执行 listeners.started(context, timeTakenToStartup) 时触发
     */
    @Override
    public void started(ConfigurableApplicationContext context, Duration timeTaken) {
        log.info("[started]-启动完成");
    }


    /**
     * IOC容器已刷新（bean创建完成），所有 runner 调用完成
     * SpringApplication.run() 执行 callRunners(context, applicationArguments) 时触发
     */
    @Override
    public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
        log.info("[ready]-准备就绪");
    }


    /**
     * SpringApplication.run() 执行throw handleRunFailure(context, ex, null) 方法时触发
     */
    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        log.info("[failed]-应用启动失败");
    }


}
